package com.samebuilding.dao.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;

import com.samebuilding.dao.FriendDAO;
import com.samebuilding.domain.Friend;
import com.samebuilding.domain.User;

public class FriendDAOImpl extends HibernateDaoSupport implements FriendDAO {
	
	private static final String FIND_ALL = "select u from Friend as f, User as u where f.userNo = ? and f.friendUserNo = u.userNo";
	private static final String FIND_COUNT_ALL = "select count(*) from Friend as f where f.userNo = ?";
	private static final String FIND_BY_TYPE = "select u from Friend as f, User as u where f.userNo = ? and f.type=? and f.friendUserNo = u.userNo";
	private static final String FIND_COUNT_BY_TYPE = "select count(*) from Friend as f where f.userNo = ? and f.type=?";
	private static final String IS_MY_FRIEND = "from Friend as f where f.userNo = ? and f.friendUserNo = ?";
	private static final String DELETE_FRIEND = "delete from Friend as f where f.userNo = ? and f.friendUserNo or f.userNo = ? and f.friendUserNo = ?";
	
	
	public void addFriend(int userNo, int friendUserNo,int type) {
		Friend f = new Friend();
		f.setUserNo(userNo);
		f.setFriendUserNo(friendUserNo);
		f.setType(type);
//		List list = this.getHibernateTemplate().find("from Friend as f where f.userNo="+userNo+" and f.friendUserNo=?",friendUserNo);
//		if(list!=null&&list.size()>0){
//			return;
//		}
		this.getHibernateTemplate().save(f);
		f.setUserNo(friendUserNo);
		f.setFriendUserNo(userNo);
		this.getHibernateTemplate().save(f);
	}

	public void deleteFriend(final int userNo, final int friendUserNo) {
		getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session s) throws HibernateException,
					SQLException {
				Query query = s.createQuery(DELETE_FRIEND);
				query.setInteger(0, userNo);
				query.setInteger(1, friendUserNo);
				query.setInteger(2, friendUserNo);
				query.setInteger(3, userNo);
				query.executeUpdate();
				return null;
			}
		});

	}
	
	@SuppressWarnings("unchecked")
	public List<User> findAllFriend(final int userNo,final int start,final int limit){
		
		return (List<User>)getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(FIND_ALL);
				query.setInteger(0, userNo);
				query.setFirstResult(start);
				query.setMaxResults(limit);
				List<User> list = query.list();
				return list;
			}
		});
		
		// return this.getHibernateTemplate().find("from Friend as f where f.userNo=?",userNo);
	}
	public List findAllFriendDWR(int userNo){
		 List friend = this.getHibernateTemplate().find("from Friend as f where f.userNo=?",userNo);
		 Iterator it = friend.iterator();
		 List user = new ArrayList();
		 while(it.hasNext()){
			 List list= this.getHibernateTemplate().find("from User as u where u.userNo=?",((Friend)it.next()).getFriendUserNo());
			 user.add(list.get(0));
		 }
		 return user;
	}
	
	@SuppressWarnings("unchecked")
	public List<User> findByType(final int userNo,final int type,final int start,final int limit) {
		
		return (List<User>)getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(FIND_BY_TYPE);
				query.setInteger(0, userNo);
				query.setInteger(1, type);
				query.setFirstResult(start);
				query.setMaxResults(limit);
				List<User> list = query.list();
				return list;
			}
		});
		
		//return this.getHibernateTemplate().find("from Friend as f where f.userNo="+userNo+" and f.type=?",type);
	}

	public int findCountAllFriend(final int userNo) {
		long count = (Long)this.getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(FIND_COUNT_ALL);
				query.setInteger(0, userNo);

				return query.uniqueResult();
			}
		});
		return (int)count;
	}

	public int findCountByType(final int userNo, final int type) {
		long count = (Long)this.getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(FIND_COUNT_BY_TYPE);
				query.setInteger(0, userNo);
				query.setInteger(1, type);
				return query.uniqueResult();
			}
		});
		return (int)count;
	}

	public List findAllFriend(final int userNo) {
		return (List)getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(FIND_ALL);
				query.setInteger(0, userNo);
				List list = query.list();
				return list;
			}
		});
	}

	@SuppressWarnings("unchecked")
	public List<User> findByType(final int userNo, final int type) {
		return (List<User>)getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(FIND_BY_TYPE);
				query.setInteger(0, userNo);
				query.setInteger(1, type);
				List<User> list = query.list();
				return list;
			}
		});
	}

	public boolean isMyFriend(final int sendUserNo, final int receiveUserNo) {
		List list = getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(IS_MY_FRIEND);
				query.setInteger(0, sendUserNo);
				query.setInteger(1, receiveUserNo);
				List list = query.list();
				return list;
			}
		});
		
		if(list == null || list.size() == 0) {
			return false;
		} else {
			return true;
		}
	}

}
